"""
SiliconFlow VLM API客户端
用于与SiliconFlow的视觉语言模型API进行通信
"""

import asyncio
import base64
import json
import logging
from typing import Optional, Dict, Any, Union
from pathlib import Path

import httpx

logger = logging.getLogger(__name__)


class VLMClient:
    """SiliconFlow视觉语言模型API客户端"""
    
    def __init__(self, api_key: str, api_url: str = "https://api.siliconflow.cn/v1/chat/completions", 
                 model_name: str = "Qwen/Qwen2-VL-72B-Instruct", timeout: int = 120):
        """
        初始化VLM客户端
        
        Args:
            api_key (str): SiliconFlow API密钥
            api_url (str): API端点URL
            model_name (str): 模型名称
            timeout (int): 请求超时时间(秒)
        """
        self.api_key = api_key
        self.api_url = api_url
        self.model_name = model_name
        self.timeout = timeout
        self.client = httpx.AsyncClient(
            timeout=httpx.Timeout(timeout),
            headers={
                "Authorization": f"Bearer {api_key}",
                "Content-Type": "application/json"
            }
        )
    
    async def close(self):
        """关闭HTTP客户端"""
        await self.client.aclose()
    
    async def _call_api(self, messages: list, temperature: float = 0.7, max_tokens: int = 2000) -> Dict[str, Any]:
        """
        调用VLM API
        
        Args:
            messages (list): 消息列表
            temperature (float): 温度参数
            max_tokens (int): 最大token数
            
        Returns:
            Dict[str, Any]: API响应
        """
        payload = {
            "model": self.model_name,
            "messages": messages,
            "temperature": temperature,
            "max_tokens": max_tokens,
            "stream": False
        }
        
        try:
            response = await self.client.post(self.api_url, json=payload)
            response.raise_for_status()
            return response.json()
        except httpx.HTTPStatusError as e:
            logger.error(f"API调用失败: {e.response.status_code} - {e.response.text}")
            raise
        except Exception as e:
            logger.error(f"API调用异常: {e}")
            raise
    
    async def analyze_image(self, image_base64: str, prompt: str = "请详细描述这张图片的内容") -> Dict[str, Any]:
        """
        分析图像内容
        
        Args:
            image_base64 (str): 图像的base64编码字符串
            prompt (str): 分析提示词
            
        Returns:
            Dict[str, Any]: 分析结果
        """
        messages = [
            {
                "role": "user",
                "content": [
                    {"type": "text", "text": prompt},
                    {"type": "image_url", "image_url": {"url": image_base64}}
                ]
            }
        ]
        
        response = await self._call_api(messages)
        return {
            "response": response["choices"][0]["message"]["content"],
            "usage": response.get("usage", {}),
            "model": response.get("model", self.model_name)
        }
    
    async def detect_objects(self, image_base64: str, prompt: str = "请检测图像中的物体并提供边界框坐标") -> Dict[str, Any]:
        """
        检测图像中的物体
        
        Args:
            image_base64 (str): 图像的base64编码字符串
            prompt (str): 检测提示词
            
        Returns:
            Dict[str, Any]: 检测结果
        """
        # 特殊提示词，鼓励模型输出坐标信息
        detection_prompt = f"{prompt}。请使用以下格式输出坐标信息：[x1, y1, x2, y2]，其中坐标基于1000x1000的标准化空间。"
        
        messages = [
            {
                "role": "user",
                "content": [
                    {"type": "text", "text": detection_prompt},
                    {"type": "image_url", "image_url": {"url": image_base64}}
                ]
            }
        ]
        
        response = await self._call_api(messages, temperature=0.1)  # 使用较低温度以获得更精确的结果
        return {
            "response": response["choices"][0]["message"]["content"],
            "usage": response.get("usage", {}),
            "model": response.get("model", self.model_name)
        }
    
    async def answer_question(self, image_base64: str, question: str) -> Dict[str, Any]:
        """
        回答关于图像的问题
        
        Args:
            image_base64 (str): 图像的base64编码字符串
            question (str): 问题
            
        Returns:
            Dict[str, Any]: 回答结果
        """
        messages = [
            {
                "role": "user",
                "content": [
                    {"type": "text", "text": question},
                    {"type": "image_url", "image_url": {"url": image_base64}}
                ]
            }
        ]
        
        response = await self._call_api(messages)
        return {
            "response": response["choices"][0]["message"]["content"],
            "usage": response.get("usage", {}),
            "model": response.get("model", self.model_name)
        }
    
    async def read_text(self, image_base64: str) -> Dict[str, Any]:
        """
        识别图像中的文字
        
        Args:
            image_base64 (str): 图像的base64编码字符串
            
        Returns:
            Dict[str, Any]: 文字识别结果
        """
        ocr_prompt = "请识别并提取图像中的所有文字内容。按照从上到下、从左到右的顺序输出文字。"
        
        messages = [
            {
                "role": "user",
                "content": [
                    {"type": "text", "text": ocr_prompt},
                    {"type": "image_url", "image_url": {"url": image_base64}}
                ]
            }
        ]
        
        response = await self._call_api(messages)
        return {
            "response": response["choices"][0]["message"]["content"],
            "usage": response.get("usage", {}),
            "model": response.get("model", self.model_name)
        }